Hệ thống quản lý trường đại học bằng PHP

1 <?php
2 if
(!defined('PASSWORD_DEFAULT')) {
3         define(
'PASSWORD_BCRYPT', 1);
4         define(
'PASSWORD_DEFAULT', PASSWORD_BCRYPT);
5 }
6
7     Class Password {
8
9         
public function __construct() {}
10
11
12         
/**
13          * Hash the password
using the specified algorithm
14          *
15          * @param
string $password The password to hash
16          * @param
int $algo The algorithm to use (Defined by PASSWORD_* constants)
17          * @param array $options The options
for the algorithm to use
18          *
19          * @
return string|false The hashed password, or false on error.
20          */

21         function password_hash($password, $algo, array $options = array()) {
22             
if (!function_exists('crypt')) {
23                 trigger_error(
"Crypt must be loaded for password_hash to function", E_USER_WARNING);
24                 
return null;
25             }
26             
if (!is_string($password)) {
27                 trigger_error(
"password_hash(): Password must be a string", E_USER_WARNING);
28                 
return null;
29             }
30             
if (!is_int($algo)) {
31                 trigger_error(
"password_hash() expects parameter 2 to be long, " . gettype($algo) . " given", E_USER_WARNING);
32                 
return null;
33             }
34             
switch ($algo) {
35                 
case PASSWORD_BCRYPT :
36                     
// Note that this is a C constant, but not exposed to PHP, so we don't define it here.
37                     $cost =
10;
38                     
if (isset($options['cost'])) {
39                         $cost = $options[
'cost'];
40                         
if ($cost < 4 || $cost > 31) {
41                             trigger_error(sprintf(
"password_hash(): Invalid bcrypt cost parameter specified: %d", $cost), E_USER_WARNING);
42                             
return null;
43                         }
44                     }
45                     
// The length of salt to generate
46                     $raw_salt_len =
16;
47                     
// The length required in the final serialization
48                     $required_salt_len =
22;
49                     $hash_format = sprintf(
"$2y$%02d$", $cost);
50                     
break;
51                 
default :
52                     trigger_error(sprintf(
"password_hash(): Unknown password hashing algorithm: %s", $algo), E_USER_WARNING);
53                     
return null;
54             }
55             
if (isset($options['salt'])) {
56                 
switch (gettype($options['salt'])) {
57                     
case 'NULL' :
58                     
case 'boolean' :
59                     
case 'integer' :
60                     
case 'double' :
61                     
case 'string' :
62                         $salt = (
string)$options['salt'];
63                         
break;
64                     
case 'object' :
65                         
if (method_exists($options['salt'], '__tostring')) {
66                             $salt = (
string)$options['salt'];
67                             
break;
68                         }
69                     
case 'array' :
70                     
case 'resource' :
71                     
default :
72                         trigger_error(
'password_hash(): Non-string salt parameter supplied', E_USER_WARNING);
73                         
return null;
74                 }
75                 
if (strlen($salt) < $required_salt_len) {
76                     trigger_error(sprintf(
"password_hash(): Provided salt is too short: %d expecting %d", strlen($salt), $required_salt_len), E_USER_WARNING);
77                     
return null;
78                 } elseif (
0 == preg_match('#^[a-zA-Z0-9./]+$#D', $salt)) {
79                     $salt = str_replace(
'+', '.', base64_encode($salt));
80                 }
81             }
else {
82                 $buffer =
'';
83                 $buffer_valid =
false;
84                 
if (function_exists('mcrypt_create_iv') && !defined('PHALANGER')) {
85                     $buffer = mcrypt_create_iv($raw_salt_len, MCRYPT_DEV_URANDOM);
86                     
if ($buffer) {
87                         $buffer_valid =
true;
88                     }
89                 }
90                 
if (!$buffer_valid && function_exists('openssl_random_pseudo_bytes')) {
91                     $buffer = openssl_random_pseudo_bytes($raw_salt_len);
92                     
if ($buffer) {
93                         $buffer_valid =
true;
94                     }
95                 }
96                 
if (!$buffer_valid && is_readable('/dev/urandom')) {
97                     $f = fopen(
'/dev/urandom', 'r');
98                     $read = strlen($buffer);
99                     
while ($read < $raw_salt_len) {
100                         $buffer .= fread($f, $raw_salt_len - $read);
101                         $read = strlen($buffer);
102                     }
103                     fclose($f);
104                     
if ($read >= $raw_salt_len) {
105                         $buffer_valid =
true;
106                     }
107                 }
108                 
if (!$buffer_valid || strlen($buffer) < $raw_salt_len) {
109                     $bl = strlen($buffer);
110                     
for ($i = 0; $i < $raw_salt_len; $i++) {
111                         
if ($i < $bl) {
112                             $buffer[$i] = $buffer[$i] ^ chr(mt_rand(
0, 255));
113                         }
else {
114                             $buffer .= chr(mt_rand(
0, 255));
115                         }
116                     }
117                 }
118                 $salt = str_replace(
'+', '.', base64_encode($buffer));
119             }
120             $salt = substr($salt,
0, $required_salt_len);
121
122             $hash = $hash_format . $salt;
123
124             $ret = crypt($password, $hash);
125
126             
if (!is_string($ret) || strlen($ret) <= 13) {
127                 
return false;
128             }
129
130             
return $ret;
131         }
132
133         
/**
134          * Get information about the password hash. Returns an array of the information
135          * that was used to generate the password hash.
136          *
137          * array(
138          *
'algo' => 1,
139          *
'algoName' => 'bcrypt',
140          *
'options' => array(
141          *
'cost' => 10,
142          * ),
143          * )
144          *
145          * @param
string $hash The password hash to extract info from
146          *
147          * @
return array The array of information about the hash.
148          */

149         function password_get_info($hash) {
150             $
return = array('algo' => 0, 'algoName' => 'unknown', 'options' => array(), );
151             
if (substr($hash, 0, 4) == '$2y$' && strlen($hash) == 60) {
152                 $
return['algo'] = PASSWORD_BCRYPT;
153                 $
return['algoName'] = 'bcrypt';
154                 list($cost) = sscanf($hash,
"$2y$%d$");
155                 $
return['options']['cost'] = $cost;
156             }
157             
return $return;
158         }
159
160         
/**
161          * Determine
if the password hash needs to be rehashed according to the options provided
162          *
163          * If the answer
is true, after validating the password using password_verify, rehash it.
164          *
165          * @param
string $hash The hash to test
166          * @param
int $algo The algorithm used for new password hashes
167          * @param array $options The options array passed to password_hash
168          *
169          * @
return boolean True if the password needs to be rehashed.
170          */

171         function password_needs_rehash($hash, $algo, array $options = array()) {
172             $info = password_get_info($hash);
173             
if ($info['algo'] != $algo) {
174                 
return true;
175             }
176             
switch ($algo) {
177                 
case PASSWORD_BCRYPT :
178                     $cost = isset($options[
'cost']) ? $options['cost'] : 10;
179                     
if ($cost != $info['options']['cost']) {
180                         
return true;
181                     }
182                     
break;
183             }
184             
return false;
185         }
186
187         
/**
188          * Verify a password against a hash
using a timing attack resistant approach
189          *
190          * @param
string $password The password to verify
191          * @param
string $hash The hash to verify against
192          *
193          * @
return boolean If the password matches the hash
194          */

195         
public function password_verify($password, $hash) {
196             
if (!function_exists('crypt')) {
197                 trigger_error(
"Crypt must be loaded for password_verify to function", E_USER_WARNING);
198                 
return false;
199             }
200             $ret = crypt($password, $hash);
201             
if (!is_string($ret) || strlen($ret) != strlen($hash) || strlen($ret) <= 13) {
202                 
return false;
203             }
204
205             $status =
0;
206             
for ($i = 0; $i < strlen($ret); $i++) {
207                 $status |= (ord($ret[$i]) ^ ord($hash[$i]));
208             }
209
210             
return $status === 0;
211         }
212
213     }


Gõ tìm kiếm nhanh...